#ifndef GRAPHCOLORING_H
#define GRAPHCOLORING_H

#include <fstream>
#include <string>
#include <iostream>
#include "Input.h"
#include "Chain.h"

using std::streampos;
using std::ofstream;
using std::string;
using std::endl;

//the main class for managing a coloring
class GraphColoringManager
{
public:
	typedef int ALGORITHMS;
	
	//bitmap for the algorithems
	static const ALGORITHMS  GREEDY					= 0x00000001;
	static const ALGORITHMS  IMPROVED_GREEDY			= 0x00000002;
	static const ALGORITHMS  IMPROVE_GROUP_WITH_GREEDY = 0x00000004;
	static const ALGORITHMS  BREAK_AND_REFILL			= 0x00000008;
	static const ALGORITHMS  SWITCH_SINGELS			= 0x00000010;
	static const ALGORITHMS  SWITCH_PAIRS				= 0x00000020;
	static const ALGORITHMS  DUMP_GROUPS_AND_REFILL	= 0x00000040;
	static const ALGORITHMS  ALL						= 0x11111111;

	static const int NUMBER_OF_TRIES_TO_FILL_CHAIN		= 3;

	enum COLORING_RESULT{IMPROVED, UNIMPROVED, BROKEN};

	//interface
	string SetupDirectory(string processForDirName, string containingDir);
	InputVariables&	ParseInputFiles(string inputFileName, string destenationColoringFileName);
	set<vector<bool> >* CreateProgramVertices();
	void CreateInitialChain(string chainFileName);
	void FillInitialChain();
	COLORING_RESULT StartTheColoring(ALGORITHMS algorithem);
	void OutputResult(string chainFileName, COLORING_RESULT coloringResult);

private:
	InputVariables	m_InputVars;
	Chain*			m_MainChain;

	bool ChainSanityCheck(Chain *chainToCheck, bool isFullCheck);
	bool GroupSanityCheck(Group *groupToCheck, Chain *relativeChain);
	void OutputIntermediateResult();
	string CleanNameStr(string strToClean);

};


#endif //GRAPHCOLORING_H
